package net.onceface.application.impl;

import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;

import javax.inject.Named;

import net.onceface.application.CategoryApplication;
import net.onceface.application.assembler.CategoryAssembler;
import net.onceface.application.dto.CategoryDTO;
import net.onceface.core.domain.Category;
import net.onceface.infra.querychannel.QueryChannelService;
import net.onceface.infra.spring.ioc.InstanceFactory;

import org.apache.commons.lang3.StringUtils;
import org.springframework.transaction.annotation.Transactional;
@Named
@Transactional
@SuppressWarnings("unchecked")
public class CategortApplicationImpl implements CategoryApplication {

	private QueryChannelService queryChannel;

	private QueryChannelService getQueryChannelService() {
		if (queryChannel == null) {
			queryChannel = InstanceFactory.getInstance(
					QueryChannelService.class, "queryChannel");
		}
		return queryChannel;
	}
	
	@Override
	public List<CategoryDTO> getList() {
		// TODO Auto-generated method stub
		List<CategoryDTO> results = getParentList();
		List<CategoryDTO> childrenCategory = getChildList();
		List<CategoryDTO> all = new ArrayList<CategoryDTO>();
		all.addAll(results);
		all.addAll(childrenCategory);
		addChildrenToParent(all);
		return results;
	}
	
	/**
	 * 传入所有分类，自动拼成分类树
	 * **/
	private void addChildrenToParent(List<CategoryDTO> all){
		LinkedHashMap<Long, CategoryDTO> map = new LinkedHashMap<Long, CategoryDTO>();
		for(CategoryDTO categoryDTO : all){
			map.put(categoryDTO.getId(), categoryDTO);
		}
		for(CategoryDTO categoryDTO : map.values()){
			Long parentId = categoryDTO.getParentId();
			if(!StringUtils.isBlank(parentId + "") && map.get(parentId) != null){
				map.get(parentId).getChildren().add(categoryDTO);
			}
		}
	}
	
	/**
	 * 查找子分类
	 * **/
	public List<CategoryDTO> getChildList() {
		StringBuilder jpql = new StringBuilder("SELECT _category FROM Category _category")
		.append(" WHERE _category.level > :level")
		.append(" AND _category.abolishDate > NOW()")
		.append(" AND _category.disabled = true")
		.append(" GROUP BY _category.id")
		.append(" ORDER BY _category.id");
		List<Category> categorys = getQueryChannelService().createJpqlQuery(jpql.toString())
				.addParameter("level", 0).list();
		return CategoryAssembler.toDTOs(categorys);
	}
	
	/**
	 * 查找父类
	 * **/
	public List<CategoryDTO> getParentList() {
		StringBuilder jpql = new StringBuilder("SELECT _category FROM Category _category")
		.append(" WHERE _category.level = :level")
		.append(" AND _category.abolishDate > NOW()")
		.append(" AND _category.disabled = true")
		.append(" GROUP BY _category.id")
		.append(" ORDER BY _category.id");
		List<Category> categorys = getQueryChannelService().createJpqlQuery(jpql.toString())
				.addParameter("level", 0).list();
		return CategoryAssembler.toDTOs(categorys);
	}

	@Override
	public List<CategoryDTO> findByParentId(Long parentId) {
		StringBuilder jpql = new StringBuilder("SELECT _category FROM Category _category")
		.append(" WHERE _category.abolishDate > NOW()")
		.append(" AND _category.disabled = true")
		.append(" AND _category.parent.id = :id");
		List<Category> categorys = getQueryChannelService().createJpqlQuery(jpql.toString())
				.addParameter("id", parentId).list();
		return CategoryAssembler.toDTOs(categorys);
	}

}
